﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define NUL '\0'

/*结构体*/
typedef struct node
{
    int year;
    int month;
    int day;//交易日
    char mingzi[20];//用户名
    char type[50];//类型
    char address[50];//地点
    long inDay;//入账日
    long num;//次数
    float money;//交易额
    float moneyLeft;//余额
    struct node* next;
}node;
node* h = NULL;//存放链表头节点常用变量
node* f = NULL;//更新功能(修改某行)会调用查询模块,此变量用来标记用户查询行的地址，在更新函数里面通过它获取修改行地址
node* z = NULL;//删除功能会调用查询模块 此变量用来记录删除结点的前结点 用以连接链表
int n = 0;//后续多个循环用到 如筛选出了符合的数据 将n置为1 最后判断如果 n==0 统一输出无相关记录

typedef struct code
{
    char mingzi[20];
    char password[20];
}code;


/*函数声明*/
int welcome();
void del();//更新(删除某行)链表
void print(node* head);//打印链表
node* createlink(int b, char N[20]);//创建链表
void check(int b);//查询
void gengxin();//更新(修改)链表
void input();//录入链表  //用到的是头插法
void inquire(int b);//查询链表  //参数int b区分 调用 普通用户 还是 管理员 的 菜单
void outlink(node* head);//输出链表到txt(保存链表)
void tongji();//根据期日区间统计
int manager();//管理员登录
int user();//用户登录
int rank();//排序的菜单函数
void Rank_check(int b);//根据多个判断条件排序
void changeNode(node*a,node*b);//交换两个结点
int update();//更新（删除or修改）
int login(int a, char N[20]);//登录



int main()
{
    //设置标题 
    system("wzy");
    welcome();
    system("pause");
    return 0;
}


/*开始界面*/
int welcome()
{
    int a;
A:system("cls");
    printf("--------------------------------------------------\n");
    printf("**************************************************\n");
    printf("请选择你的身份： 1---用户   2---管理员   3---退出\n");
    printf("**************************************************\n");
    printf("--------------------------------------------------\n");
    scanf("%d", &a);
    switch (a)
    {
    case 1:user(); goto A;
    case 2:manager(); goto A;
    case 3:break;
    default:printf("error\n"); goto A;
    }
    return 0;
}


/*用户界面*/
int user()
{
    int a;
    char N[20];
    printf("请输入用户名:\n");//因为要创建链表 所以输入用户名操作没写在公共的login里面(其实也可以写在里面)
    fflush(stdin);
    scanf("%s", &N);
    a = login(1, N);//登录功能
    if (a == 0)goto B;
    h = createlink(1, N);//根据用户名创建链表,函数里面将会通过用户名对读取的文档数据进行筛选,因为用户只能看自己的记录
    if (h == NULL)
    {
        printf("无记录\n");
        goto B;
    }
A:system("cls");
    printf("-----------------------------------------------\n");
    printf("***********************************************\n");
    printf(" 1---查询   2---排序   3---统计    4---退出登录\n");
    printf("***********************************************\n");
    printf("-----------------------------------------------\n");
    scanf("%d", &a);
    switch (a)
    {
    case 1:inquire(2); goto A;
    case 2:rank(); goto A;
    case 3:tongji(); goto A;
    case 4:system("pause"); break;
    default:printf("error\n"); goto A;
    }
    free(h);//释放头节点
B:return 0;
}


/*管理员界面*/
int manager()
{
    int a;
    char M[20];
    char N[20] = "manager";//将要传入createlink的参数。此为管理员 写死manager
    printf("请输入用户名:\n");
    fflush(stdin);
    scanf("%s", &M);
    a = login(2, M);
    if (a == 0)goto B;

    h = createlink(1, N);//根据管理员权限创建链表
A:system("cls");
    printf("--------------------------------------------------------------------\n");
    printf("********************************************************************\n");
    printf("1---查询   2---排序   3---统计   4---录入   5---更新   6---退出登录  \n");
    printf("********************************************************************\n");
    printf("--------------------------------------------------------------------\n");
    scanf("%d", &a);
    switch (a)
    {
    case 1:inquire(1); goto A;
    case 2:rank(); goto A;
    case 3:tongji(); goto A;
    case 4:input(); goto A;
    case 5:update(); goto A;
    case 6:system("pause"); break;
    default:printf("error\n"); goto A;
    }
    free(h);
B:return 0;
}


/*查询功能*/
void inquire(int b)//int b区分 普通用户 管理员 菜单
{
    int a;
A:system("cls");
    if (b == 1)//管理员菜单
    {
        a = 5;
        printf("-------------------------------------------------------------------------------------------------------------\n");
        printf("*************************************************************************************************************\n");
        printf("    1---按固定时段查询   2---按日期区间段查询   3---按交易金额查询   4---已删除记录查询   5---返回\n");
        printf("*************************************************************************************************************\n");
        printf("-------------------------------------------------------------------------------------------------------------\n");
        fflush(stdin);
        scanf("%d", &a);
        switch (a)
        {
        case 1:check(1); goto A;
        case 2:check(2); goto A;
        case 3:check(3); goto A;
        case 4:check(4); goto A;
        case 5:break;
        default:printf("请重新输入");
        }
    }
    if (b == 2)//普通用户菜单
    {
        a = 4;
        printf("-------------------------------------------------------------------------------------------------------------\n");
        printf("*************************************************************************************************************\n");
        printf("              1---按固定时段查询   2---按日期区间段查询   3---按交易金额查询     4---返回 \n");
        printf("*************************************************************************************************************\n");
        printf("-------------------------------------------------------------------------------------------------------------\n");
        fflush(stdin);
        scanf("%d", &a);
        switch (a)
        {
        case 1:check(1); goto A;
        case 2:check(2); goto A;
        case 3:check(3); goto A;
        case 4:break;
        default:printf("请重新输入");
        }
    }
}



/*排序功能*/
int rank()
{
    int a;
A:system("cls");
    printf("-------------------------------------------------------------------------------------\n");
    printf("*************************************************************************************\n");
    printf("请选择排序方式    1---按金额排序   2---按交易日期排序   3---按交易次数排序   4---返回\n");
    printf("*************************************************************************************\n");
    printf("-------------------------------------------------------------------------------------\n");
    scanf("%d", &a);
    switch (a)
    {
    case 1: Rank_check(1); break;
    case 2: Rank_check(2); break;
    case 3: Rank_check(3); break;
    case 4: goto B;
    default: printf("error\n");
    }
    goto A;
B:return 0;
}


/*更新功能*/
int update()
{
    int a;
A:system("cls");
    printf("----------------------------------------------------\n");
    printf("****************************************************\n");
    printf("  请选择    1---修改信息   2---删除信息   3---返回 \n");
    printf("****************************************************\n");
    printf("----------------------------------------------------\n");
    scanf("%d", &a);
    switch (a)
    {
    case 1:gengxin(); break;
    case 2:del(); break;
    case 3:goto B;
    default:printf("error\n");
    }
    goto A;
B:return 0;
}


/*从消费记录文件中读取数据存入链表 */
node* createlink(int b, char N[20])
{
    node* p;
    node* q1;
    FILE* r;
    node* head;
    char M[20] = "manager";

    head = (node*)malloc(sizeof(node));//申请头节点空间
    p = q1 = head;//先让功能指针指向头节点

    if (b == 1)
    {
        r = fopen("fee.txt", "r");
    }
    if (b == 2)
    {
        r = fopen("fee_del.txt", "r");
    }
    if (r == NULL)
    {
        printf("打开文件失败!");
        free(head);//释放头节点空间
        return NULL;
    }
    if (strcmp(M, N) == 0)//如果是管理员
    {
        while (fscanf(r, "%s %d %d %d %ld %f %f %s %ld %s", &q1->mingzi, &q1->year, &q1->month, &q1->day, &q1->inDay, &q1->money, &q1->moneyLeft, &q1->type, &q1->num, &q1->address) != EOF)
        {//用q1记录当前行 循环构建链表
            p = q1;
            q1 = (node*)calloc(sizeof(node), 1);
            p->next = q1;
        }
    }
    else//普通用户
    {
        while (fscanf(r, "%s %d %d %d %ld %f %f %s %ld %s", &q1->mingzi, &q1->year, &q1->month, &q1->day, &q1->inDay, &q1->money, &q1->moneyLeft, &q1->type, &q1->num, &q1->address) != EOF)
        {//用q1记录当前行 循环构建链表
            if (strcmp(q1->mingzi, N) == 0)//当前行名字 等于用户输入的用户名 才添加到链表 因为用户只能查询自己的数据
            {
                p = q1;
                q1 = (node*)calloc(sizeof(node), 1);
                p->next = q1;
            }
        }
        if (strcmp(p->mingzi, N) != 0)
        {
            p = NULL;
            q1 = NULL;
            free(head);
            head = (node*)malloc(sizeof(node));
            strcpy(head->mingzi, "无记录");
            head->year = 0000;
            head->month = 00;
            head->day = 00;
            head->inDay = 00000000;
            head->money = 0.00;
            head->moneyLeft = 0.00;
            head->num = 0;
            strcpy(head->type, "无");
            strcpy(head->address, "无");
            head->next = NULL;
            return head;
        }
    }
    fclose(r);
    p->next = NULL;
    return head;
}


/*保存功能*/
void outlink(node* head)
{
    FILE* w;
    node* q1;
    q1 = head;

    w = fopen("fee.txt", "w");
    if (w == NULL)
    {
        printf("打开文件失败!");
        return;
    }
    while (q1)
    {
        //输出链表节点数据到文件fee.txt 
        fprintf(w, "%s %d %d %d %ld %f %f %s %ld %s\n", q1->mingzi, q1->year, q1->month, q1->day, q1->inDay, q1->money, q1->moneyLeft, q1->type, q1->num, q1->address);
        q1 = q1->next;
    }
    printf("\n");
    fprintf(w, "\n");
    fclose(w);
    return;
}


/*查询功能*/
void check(int b)
{
    node* pt, * q;

    system("cls");

    pt = (node*)malloc(sizeof(node));
    q = pt;
    pt->next = h;
    if (b == 1)//固定日期查询
    {
        int y, m, d;
        printf("请输入想要查询的时间  例如：2021 1 3\n");
        scanf("%d %d %d\n", &y, &m, &d);
        while (pt->next != NULL)
        {//循环遍历链表
            if (((pt->next->year) == y) && ((pt->next->month) == m) && ((pt->next->day) == d))
            {//输入的年月日 跟 查询记录的年月日全等
                n = 1;
                f = pt->next;
                printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", f->mingzi, y, m, d, f->inDay, f->money, f->moneyLeft, f->type, f->num, f->address);
                z = pt;
            }
            pt = pt->next;//指向下一节点
        }
    }
    if (b == 2)//按日期区间段查询
    {
        int y1, y2, m1, m2, d1, d2;
        printf("请输入想要查询的时间段  例如：2021 1 12 2021 3 20\n");
        scanf("%d %d %d %d %d %d", &y1, &m1, &d1, &y2, &m2, &d2);
        int date, date1, date2;
        while (pt->next != NULL)
        {
            //按权重比较三个日期大小  年*2021  月*31  日*1 相加
            date = pt->next->year * 365 + pt->next->month * 31 + pt->next->day;//当前查询行
            date1 = y1 * 365 + m1 * 31 + d1;//起始日期
            date2 = y2 * 365 + m2 * 31 + d2;//结束日期
            if (date1 < date && date < date2)
            {
                n = 1;
                f = pt->next;
                printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", f->mingzi, f->year, f->month, f->day, f->inDay, f->money, f->moneyLeft, f->type, f->num, f->address);
                z = pt;
            }
            pt = pt->next;
        }
    }
    if (b == 3)//按交易金额查询
    {
        float m;
        printf("请输入想要查询的金额\n");
        scanf("%f", &m);
        while (pt->next != NULL)
        {
            if ((int)(pt->next->money * 10) == (int)(m * 10))//(int)强制类型转换 计算出金额做对比
            {
                n = 1;
                f = pt->next;
                printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", f->mingzi, f->year, f->month, f->day, f->inDay, f->money, f->moneyLeft, f->type, f->num, f->address);
                z = pt;
            }
            pt = pt->next;
        }
    }
    if (b == 4)//查询已删除记录 
    {
        node* pt, * p;
        int n = 1;
        char N[20] = "manager";
        pt = createlink(2, N);//查看已删除记录需要以管理员身份创建链表
        p = pt;
        while (pt != NULL)
        {
            printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", pt->mingzi, pt->year, pt->month, pt->day, pt->inDay, pt->money, pt->moneyLeft, pt->type, pt->num, pt->address);

            pt = pt->next;

        }
        free(p);

    }
    if (n == 0)
    {
        f = NULL;
        z = NULL;
        printf("无相关记录\n");
    }
    n = 0;
    if (z == q)z = NULL;
    q->next = NULL;
    free(q);
    system("pause");
}


//交换两个结点
void changeNode(node *a,node *b) {//传入参数为两个结点的地址

    node copyNode, * copyPtr;//临时标记节点和next指针的工具变量
    //交换结点内容
    copyNode = *a;
    *a = *b;
    *b = copyNode;
    //再交换结点next指针域地址
    copyPtr = a->next;
    a->next = b->next;
    b->next = copyPtr;
}

/*排序功能*/     //h头指针是否受影响未知 
void Rank_check(int b)
{//此排序功能所用皆为冒泡排序   两层循环  中间判断是否交换两个结点  

    node* pt;//链表头节点指针
    node* p1, * p2;//循环用的两个工具指针
    node copyNode, * copyPtr;//临时标记节点和next指针的工具变量
    int xu;

    printf("请选择排序方式：1---升序    2---降序\n");
    scanf("%d", &xu);

    pt = h;

    if (b == 1)//按金额排序
    {
        if (xu == 1)//升序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->money) > (p2->money))
                    {
                        changeNode(p1,p2);//交换两个结点
                    }
                }
        }
        else if (xu == 2)//降序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->money) < (p2->money))
                    {
                        changeNode(p1, p2);
                    }
                }
        }
        while (pt != NULL)//循环输出排序后的链表
        {
            n = 1;
            printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", pt->mingzi, pt->year, pt->month, pt->day, pt->inDay, pt->money, pt->moneyLeft, pt->type, pt->num, pt->address);
            pt = pt->next;
        }
    }
    else if (b == 2)//按交易日期排序
    {
        if (xu == 1)//升序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->inDay) > (p2->inDay))
                    {
                        changeNode(p1, p2);
                    }
                }
        }
        else if (xu == 2)//降序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->inDay) < (p2->inDay))
                    {
                        changeNode(p1, p2);
                    }
                }
        }
        while (pt != NULL)//循环输出排序后的链表
        {
            n = 1;
            printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", pt->mingzi, pt->year, pt->month, pt->day, pt->inDay, pt->money, pt->moneyLeft, pt->type, pt->num, pt->address);
            pt = pt->next;
        }
    }
    else if (b == 3)//按交易次数排序
    {
        if (xu == 1)//升序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->num) > (p2->num))
                    {
                        changeNode(p1, p2);
                    }
                }
        }
        else if (xu == 2)//降序
        {
            for (p1 = pt; p1 != NULL; p1 = p1->next)
                for (p2 = p1->next; p2 != NULL; p2 = p2->next)
                {
                    if ((p1->num) < (p2->num))
                    {
                        changeNode(p1, p2);
                    }
                }
        }
        while (pt != NULL)//循环输出排序后的链表
        {
            n = 1;
            printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", pt->mingzi, pt->year, pt->month, pt->day, pt->inDay, pt->money, pt->moneyLeft, pt->type, pt->num, pt->address);
            pt = pt->next;
        }
    }
    if (n == 0)
    {
        printf("error\n");
    }
    system("pause");
}


/*统计功能*/
void tongji()
{
    node* pt;//存放头节点地址
    int y1, y2, m1, m2, d1, d2;//用来存放两个时间段的年 月 日的变量
    float total = 0;//总计

    pt = h;

    printf("请输入想要查询的时间段  例如：2021 1 12 2021 3 20\n");
    scanf("%d %d %d %d %d %d\n", &y1, &m1, &d1, &y2, &m2, &d2);

    int date, date1, date2;
    while (pt != NULL)
    {
        //按权重比较三个日期大小  年*2021  月*31  日*1 相加
        date = pt->year * 365 + pt->month * 31 + pt->day;//当前行日期
        date1 = y1 * 365 + m1 * 31 + d1;//开始日期
        date2 = y2 * 365 + m2 * 31 + d2;//结束日期
        if (date1 < date && date < date2)//判断日期在区间内
        {//金额相加
            n = 1;
            total = total + (pt->money);
        }
        pt = pt->next;//指向下一个结点
    }
    printf("该段时间的交易总额为： %f\n", total);
    if (n == 0)
    {
        printf("没有相关的交易记录\n");
    }
    system("pause");
}


/*录入功能*/  //头插法 
void input()
{
    node* p, * q;
    p = h;
    do {
        q = (node*)malloc(sizeof(node));//申请一个存储空间
        system("cls");
        printf("是否继续录入 Y/N\n");
        if (getchar() == 'N') break;
        printf("请输入：姓名， 交易日期，入账日期，交易额，交易后余额，交易类型，交易次数，交易地点\n");
        printf("例如：夏雨雪 2021 9 12 20210912 3.1 35.15 POS 90 南苑\n");
        //将用户输入的数据行插入到q指向的存储空间内
        scanf("%s %d %d %d %ld %f %f %s %ld %s\n", &q->mingzi, &q->year, &q->month, &q->day, &q->inDay, &q->money, &q->moneyLeft, &q->type, &q->num, &q->address);
        printf("是否录入 Y/N\n");
        if (getchar() == 'N') break;
        q->next = p;//q的指针域存放链表头结点地址，那么q就成了新的头结点
        p = q;//p = q  让p指向现在新的头结点，下次录入会重新申请q存储空间并录入一个新结点，它又会成为新的头结点
    } while (1);
    h = p;
    free(q);//释放q
    outlink(h);//输出链表到txt(保存链表)
    system("pause");
}


/*更新功能*/
void gengxin()
{
    int a;
    node* temp;
    //char ch;
    printf("是否需要展示所有记录？Y/N \n");
    fflush(stdin);
    if (getchar() == 'Y')
        print(h);//打印链表内容
    printf("通过查询锁定需要修改的信息位置\n");
    system("pause");
A:inquire(2);//根据查询函数定位要查询的数据行，并通过全局变量f保存（f申明在本cpp开头）
    temp = f;//拿到查询函数定位到的地址
    if (temp == NULL)
    {//如果没拿到地址，查询失败
        printf("查询失败\n");
        goto B;
    }
    //输出该行
    printf("姓名：%s 交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", temp->mingzi, temp->year, temp->month, temp->day, temp->inDay, temp->money, temp->moneyLeft, temp->type, temp->num, temp->address);
    //用户确认
    printf("是否要修改该信息 Y/N\n");
    fflush(stdin);
    if (getchar() == 'Y')
    {
        getchar();
        //选择修改的字段
        printf("请选择您想要修改的信息：0---姓名  1---交易日期   2---入账日期   3---交易额   4---交易后余额   5---交易类型   6---交易次数   7---交易地点\n");
        fflush(stdin);
        scanf("%d", &a);
        getchar();
        //根据用户选择的字段修改
        switch (a)
        {
        case 0:printf("请输入您想要修改的姓名：例：藏星\n"); scanf("%s", &temp->mingzi); break;
        case 1:printf("请输入您想要修改的交易日期：例：2022 3 5\n"); scanf("%d %d %d", &temp->year, &temp->month, &temp->day); break;
        case 2:printf("请输入您想要修改的入账日期：例：20200204\n"); scanf("%ld", &temp->inDay); break;
        case 3:printf("请输入您想要修改的交易额：例：4.3\n"); scanf("%f", &temp->money); break;
        case 4:printf("请输入您想要修改的交易后余额：例：45.2\n"); scanf("%f", &temp->moneyLeft); break;
        case 5:printf("请输入您想要修改的交易类型： 例：POS\n"); scanf("%s", &temp->type); break;
        case 6:printf("请输入您想要修改的交易次数：例：123\n"); scanf("%ld", &temp->num); break;
        case 7:printf("请输入您想要修改的交易地点：例：南苑\n"); scanf("%s", &temp->address); break;
        default:printf("error\n");
        }
        printf("更新完成\n");
        //打印修改后的数据
        printf("姓名：%s 交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", temp->mingzi, temp->year, temp->month, temp->day, temp->inDay, temp->money, temp->moneyLeft, temp->type, temp->num, temp->address);
    }
    //用户确认
    printf("是否要继续更新 Y/N \n");
    fflush(stdin);
    if (getchar() == 'Y')goto A;
B:outlink(h);//输出链表到txt(保存链表)
    system("pause");
}


/*管理员查询*/
void del()
{
    //int a=0;
    node* temp, * q;
    //char ch;
    FILE* w;

    printf("是否需要展示所有记录？Y/N \n");
    fflush(stdin);
    if (getchar() == 'Y')
        print(h);//打印输出所有记录
    printf("通过查询锁定需要删除的信息位置\n");
    system("pause");

    //打开文件
    w = fopen("fee_del.txt", "at");
    if (w == NULL)
    {
        printf("打开文件失败");
        goto B;
    }
A:inquire(2);//通过查询函数 用全局变量f记录选定行   z记录选定行的前一行，以便使因删除操作断裂的链表连接
    temp = f;
    if (temp == NULL)
    {
        printf("查询失败\n");
        return;
    }
    q = z;
    printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", temp->mingzi, temp->year, temp->month, temp->day, temp->inDay, temp->money, temp->moneyLeft, temp->type, temp->num, temp->address);
    printf("是否要删除该条信息 Y/N\n");
    fflush(stdin);
    if (getchar() == 'Y')
    {
        fprintf(w, "%s %d %d %d %ld %f %f %s %ld %s\n", temp->mingzi, temp->year, temp->month, temp->day, temp->inDay, temp->money, temp->moneyLeft, temp->type, temp->num, temp->address);
    }
    //（举例1 2 3 删除掉2  让1接3 此处z标记1，f标记2,f的next是3）
    if (temp == h)
    {//如果删除行是头结点,则直接让头结点标记为头结点的下一个结点
        h = h->next;
        temp->next = NULL;//清空已脱离链表的头结点
        free(temp);//释放
    }
    else
    {//普通情况（删除的结点(txt行)非头结点）
        q->next = temp->next;//删除结点的前结点指向删除节点的后结点（这样就将删除节点从链表剔除了）
        temp->next = NULL;//此两步清空删除的结点
        free(temp);//此两步清空删除的结点
    }
    printf("删除成功\n");
    printf("是否继续执行删除操作 Y/N\n");
    fflush(stdin);
    if (getchar() == 'Y')goto A;
    printf("\n");
B:fprintf(w, "\n");
    fclose(w);
    outlink(h);//输出链表到txt(保存链表)
    system("pause");
}


/*打印链表内容*/
void print(node* head)
{
    node* pt;
    pt = head;
    while (pt != NULL)
    {
        printf("姓名：%s  交易日期：%d年%d月%d日  入账日期：%ld  交易额：%f  交易后余额：%f  交易类型：%s  交易次数：%ld  交易地点：%s\n", pt->mingzi, pt->year, pt->month, pt->day, pt->inDay, pt->money, pt->moneyLeft, pt->type, pt->num, pt->address);
        pt = pt->next;
    }
}


/*登录功能*/
int login(int a, char N[20])
{
    FILE* r;
    char UserName[20];
    char UserPassword[20];
    char C[20];
    _int64 number, number1;
    printf("请输入学号/管理员号:\n");
    fflush(stdin);
    scanf("%lld", &number);
    printf("请输入密码:\n");
    fflush(stdin);
    scanf("%s", &C);
    if (a == 1)//用户
    {
        r = fopen("qwq.txt", "r+");
    }
    else//管理员
    {
        r = fopen("qaq.txt", "r+");
    }
    while (fscanf(r, "%s  %lld  %s\n", &UserName, &number1, &UserPassword) != EOF)
    {//循环用户/管理员表 查找是否有符合下面if语句的行
        if ((strcmp(UserName, N) == 0) && (strcmp(UserPassword, C) == 0) && (number == number1))
        {//用户名 密码 编号都相等 则登录成功
            fclose(r);
            printf("登录成功！\n");
            system("pause");
            return 1;//登录成功调用return 终止函数 返回1
        }
    }
    fclose(r);
    printf("登录失败！\n");
    system("pause");
    return 0;//如果上面while循环没有任何一条记录符合用户输入 则会在这里返回0
}